package transform.inline

import org.objectweb.asm.AnnotationVisitor
import org.objectweb.asm.Attribute
import org.objectweb.asm.Handle
import org.objectweb.asm.Label
import org.objectweb.asm.MethodVisitor
import org.objectweb.asm.Opcodes
import org.objectweb.asm.Type
import org.objectweb.asm.TypePath

import java.lang.reflect.Field

class MethodInliner extends MethodVisitor {

    private final Map<String, Integer> resourceIds

    MethodInliner(MethodVisitor methodVisitor, Map<String, Integer> resourceIds) {
        super(Opcodes.ASM7, methodVisitor)
        this.resourceIds = resourceIds
    }

    @Override
    void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) {
        //println("visitMethodInsn -------opcode=$opcode  owner=$owner  name=$name  descriptor=$descriptor")
        if (owner.startsWith("com/xfhy/mylibrary2/")) {
            super.visitMethodInsn(opcode, owner.replaceAll("com/xfhy/mylibrary2/", "cao/nim/dasjhdk/"), name, descriptor, isInterface)
            return
        }
        super.visitMethodInsn(opcode, owner, name, descriptor, isInterface)
    }

    @Override
    void visitFieldInsn(int opcode, String owner, String name, String descriptor) {
//        println("visitFieldInsn -------opcode=$opcode  owner=$owner  name=$name  descriptor=$descriptor")
        if (owner.startsWith("com/xfhy/mylibrary2/")) {
            super.visitFieldInsn(opcode, owner.replaceAll("com/xfhy/mylibrary2/", "cao/nim/dasjhdk/"), name, descriptor)
            return
        }
//        if (opcode == Opcodes.GETSTATIC) {
//            // 检查是否引用了R资源
//            if (owner.contains("/R\$")) {
//                // 获取资源ID
//                Integer resourceId = resourceIds.get(name)
//                if (resourceId != null) {
//                    // 将资源ID直接写入字节码
//                    mv.visitLdcInsn(resourceId)
//                    return
//                }
//            }
//        }

        super.visitFieldInsn(opcode, owner, name, descriptor)
    }

    @Override
    void visitInvokeDynamicInsn(String name, String descriptor, Handle bootstrapMethodHandle, Object... bootstrapMethodArguments) {
//        println("visitInvokeDynamicInsn .%%%%%,.  name=$name  descriptor=$descriptor")
        if (name.startsWith("com/xfhy/mylibrary2/")) {
            super.visitInvokeDynamicInsn(name.replaceAll("com/xfhy/mylibrary2/", "cao/nim/dasjhdk/"), descriptor, bootstrapMethodHandle, bootstrapMethodArguments)
            return
        }
        super.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments)
    }

    @Override
    void visitLocalVariable(String name, String descriptor, String signature, Label start, Label end, int index) {
        //println("visitLocalVariable ..%%%%%,.  name=$name  descriptor=$descriptor signature=$signature")
        if (descriptor.startsWith("L" + "com/xfhy/mylibrary2/")) {
            super.visitLocalVariable(name, descriptor.replaceAll("com/xfhy/mylibrary2/", "cao/nim/dasjhdk/"), signature, start, end, index)
            return
        }
        super.visitLocalVariable(name, descriptor, signature, start, end, index)
    }

    @Override
    void visitMethodInsn(int opcode, String owner, String name, String descriptor) {
        super.visitMethodInsn(opcode, owner, name, descriptor)
    }

    @Override
    void visitJumpInsn(int opcode, Label label) {
        super.visitJumpInsn(opcode, label)
    }

    @Override
    void visitLabel(Label label) {
        super.visitLabel(label)
    }

    @Override
    void visitTypeInsn(int opcode, String type) {
        super.visitTypeInsn(opcode, type)
    }

    @Override
    AnnotationVisitor visitInsnAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) {
        return super.visitInsnAnnotation(typeRef, typePath, descriptor, visible)
    }

    @Override
    AnnotationVisitor visitTryCatchAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) {
        return super.visitTryCatchAnnotation(typeRef, typePath, descriptor, visible)
    }

    @Override
    AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
        return super.visitAnnotation(descriptor, visible)
    }

    @Override
    AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) {
        return super.visitTypeAnnotation(typeRef, typePath, descriptor, visible)
    }

    @Override
    AnnotationVisitor visitLocalVariableAnnotation(int typeRef, TypePath typePath, Label[] start, Label[] end, int[] index, String descriptor, boolean visible) {
        return super.visitLocalVariableAnnotation(typeRef, typePath, start, end, index, descriptor, visible)
    }

    @Override
    AnnotationVisitor visitParameterAnnotation(int parameter, String descriptor, boolean visible) {
        return super.visitParameterAnnotation(parameter, descriptor, visible)
    }

    @Override
    void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
        super.visitTryCatchBlock(start, end, handler, type)
    }

    @Override
    void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
        super.visitTableSwitchInsn(min, max, dflt, labels)
    }

    @Override
    void visitMultiANewArrayInsn(String descriptor, int numDimensions) {
        super.visitMultiANewArrayInsn(descriptor, numDimensions)
    }

    @Override
    void visitAttribute(Attribute attribute) {
        super.visitAttribute(attribute)
    }

    @Override
    void visitLineNumber(int line, Label start) {
        super.visitLineNumber(line, start)
    }

    @Override
    void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
        super.visitLookupSwitchInsn(dflt, keys, labels)
    }

    @Override
    void visitLdcInsn(Object value) {

        // 我在onCreate里面写了句        startActivity(new Intent(this, MySecondActivity.class));
        // 就需要用到下面的代码,才能替换成功
        if (value instanceof Type && value.descriptor.contains("com/xfhy/mylibrary2/")) {
//            println("---- visitLdcInsn  value=$value")

            try {
                // 反射valueBuffer一个字符串,valueEnd是该字符串的长度
                def clazz = Type.class
                def valueBufferField = clazz.getDeclaredField("valueBuffer")
                valueBufferField.setAccessible(true)
                def valueEndField = clazz.getDeclaredField("valueEnd")
                valueEndField.setAccessible(true)
                def oldValueBuffer = valueBufferField.get(value) as String
                def newValueBuffer = oldValueBuffer.replaceAll("com/xfhy/mylibrary2/", "cao/nim/dasjhdk/")
                valueBufferField.set(value, newValueBuffer)
                valueEndField.set(value, newValueBuffer.length())
                super.visitLdcInsn(value)
                println("开始替换 成功了 11111")
                return
            } catch (Exception e) {
                e.printStackTrace()
            }
        }
        println("visitLdcInsn  value=$value")
        super.visitLdcInsn(value)
    }
}